﻿// week3.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include "opencv2/opencv.hpp"   
#include"opencv2/xfeatures2d.hpp" 

using namespace cv;
using namespace std;
using namespace xfeatures2d;
int labelTargets(Mat &src, Mat &mask, int thresh = 100);
int main() {
	char fn[] = "C:\\opencv\\sources\\samples\\data\\vtest.avi";
	VideoCapture capture(fn);
	Mat img, foreGround, backGround, fgMask;
	Ptr<BackgroundSubtractor>pBgModel = createBackgroundSubtractorMOG2().dynamicCast<BackgroundSubtractor>();
	if (!capture.isOpened())
	{
		cout << "无法打开视频" << fn << endl;
	}
	double rate = capture.get(CV_CAP_PROP_FPS);
	bool stop(false);
	Mat frame;
	int delay = 1000 / rate;
	while (!stop) {
		if (!capture.read(frame))
			break;
		resize(frame, img, Size(frame.cols / 2, frame.rows / 2), INTER_LINEAR);
		if (foreGround.empty()) {
			foreGround.create(img.size(), img.type());
		}
		pBgModel->apply(img, fgMask);
		threshold(fgMask, fgMask, 128, 255, THRESH_BINARY);
		foreGround = Scalar::all(0);
		img.copyTo(foreGround, fgMask);
		int nTargets = labelTargets(img, fgMask);
		pBgModel->getBackgroundImage(backGround);
		imshow("source", img);
		imshow("foreground", foreGround);
		imshow("mask", fgMask);
		imshow("background", backGround);
		cout << "共检测到" << nTargets << "个目标" << endl;
		char key = waitKey(delay);
		if (key==27)
			stop = true;
	}
	capture.release();
	waitKey();
}
int labelTargets(Mat &src, Mat &mask, int thresh) {
	Mat seg = mask.clone();
	vector<vector<Point>> cnts;
	findContours(seg, cnts, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
	float area;
	Rect rect;
	int count = 0;
	string strCount;
	for (int i = cnts.size() - 1; i >= 0; i--) {
		vector<Point>c = cnts[i];
		area = contourArea(c);
		if (area < thresh)
			continue;
		count++;
		rect = boundingRect(c);
		rectangle(src, rect, Scalar(0, 0, 0xff), 1);
		stringstream ss;
		ss << count;
		ss >> strCount;
		putText(src, strCount, Point(rect.x, rect.y), CV_FONT_HERSHEY_PLAIN, 0.5, Scalar(0, 0xff, 0));
		
	}
	return count;
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门提示: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
